Creating Table Navigation Buttons

A common feature of many applications is a series of navigation buttons that allow users to move through a table. These typically include buttons to move the record pointer to the next or prior record in the table, as well as to the top or bottom record in the table.

Designing the Navigation Buttons

Each of the buttons will have some characteristics and functionality in common, so it is a good idea to create a navigation button class. Then the individual buttons can easily derive this common appearance and functionality. This parent class is the Navbutton class defined later in this section.

Once the parent class is defined, the following subclasses define the functionality and appearance specific to each of the four navigation buttons: navTop, navPrior, navNext, navBottom.

Finally, a container class, vcr, is created and each of the navigation buttons is added to the container class. The container can be added to a form or a toolbar to provide table navigation functionality.

To create Navbutton, save the following six class definitions (Navbutton, navTop, navBottom, navPrior, navNext, and vcr) to a program file such as Navclass.prg.

Definition of the Generic Navigation Commandbutton Class

Code Comments

DEFINE CLASS Navbutton AS

COMMANDBUTTON

Height = 25

Width = 25

TableAlias = ""

Define the parent class of the navigation buttons. Give the class some dimensions.

Include a custom property, TableAlias, to hold the name of the alias to navigate through.

PROCEDURE Click

IF NOT EMPTY(This.TableAlias)

SELECT (This.TableAlias)

ENDIF

ENDPROC

If TableAlias has been set, this parent class procedure selects the alias before the actual navigation code in the subclasses is executed. Otherwise, assume that the user wants to navigate through the table in the currently selected work area.

PROCEDURE RefreshForm

_SCREEN.ActiveForm.Refresh

ENDPROC

Using _SCREEN.ActiveForm.Refresh instead of THISFORM.Refresh allows you to add the class to a form or a toolbar and have it function equally well.

ENDDEFINE

End the class definition.

The specific navigation buttons are all based on the Navbutton class. The following code defines the Top button for the set of navigation buttons. The remaining three navigation buttons are defined in the following table. The four class definitions are similar, so only the first one has extensive comments.

Definition of the Top Navigation Button Class

Code Comments

DEFINE CLASS navTop AS Navbutton

Caption = "|<"

Define the Top navigation button class and set the Caption property.

PROCEDURE Click

Create method code to be executed when the Click event for the control occurs.

DODEFAULT( )

GO TOP

THIS.RefreshForm

Call the Click event code in the parent class, Navbutton, so that the appropriate alias can be selected if the TableAlias property has been set. Include the code to set the record pointer to the first record in the table: GO TOP. Call the RefreshForm method in the parent class. It is not necessary to use the scope resolution operator (::) in this case because there is no method in the subclass with the same name as the method in the parent class. On the other hand, both the parent and the subclass have method code for the Click event.

ENDPROC

End the Click procedure.

ENDDEFINE

End the class definition.

The other navigation buttons have similar class definitions.

Definition of the Other Navigation Button Classes

Code Comments

DEFINE CLASS navNext AS Navbutton

Caption = ">"

Define the Next navigation button class and set the Caption property.

PROCEDURE Click

DODEFAULT( )

SKIP 1

IF EOF( )

GO BOTTOM

ENDIF

THIS.RefreshForm

ENDPROC

ENDDEFINE

Include the code to set the record pointer to the next record in the table. End the class definition.

DEFINE CLASS navPrior AS Navbutton

Caption = "<"

Define the Prior navigation button class and set the Caption property.

PROCEDURE Click

DODEFAULT( )

SKIP –1

IF BOF( )

GO TOP

ENDIF

THIS.RefreshForm

ENDPROC

ENDDEFINE

Include the code to set the record pointer to the previous record in the table. End the class definition.

DEFINE CLASS navBottom AS

Navbutton

Caption = ">|"

Define the Bottom navigation button class and set the Caption property.

PROCEDURE Click

DODEFAULT( )

GO BOTTOM

THIS.RefreshForm

ENDPROC

ENDDEFINE

Include the code to set the record pointer to the bottom record in the table. End the class definition.

The following class definition contains all four navigation buttons so that they can be added as a unit to a form. The class also includes a method to set the TableAlias property of the buttons.

Definition of a Table Navigation Control Class

Code Comments

DEFINE CLASS vcr AS CONTAINER

Height = 25

Width = 100

Left = 3

Top = 3

Begin the class definition. The Height property is set to the same height as the command buttons it will contain.

ADD OBJECT cmdTop AS navTop ;

WITH Left = 0

ADD OBJECT cmdPrior AS navPrior ;

WITH Left = 25

ADD OBJECT cmdNext AS navNext ;

WITH Left = 50

ADD OBJECT cmdBot AS navBottom ;

WITH Left = 75

Add the navigation buttons.

PROCEDURE SetTable(cTableAlias)

IF TYPE("cTableAlias") = 'C'

THIS.cmdTop.TableAlias = ;

cTableAlias

THIS.cmdPrior.TableAlias = ;

cTableAlias

THIS.cmdNext.TableAlias = ;

cTableAlias

THIS.cmdBot.TableAlias = ;

cTableAlias

ENDIF

ENDPROC

This method is used to set the TableAlias property of the buttons. TableAlias is defined in the parent class Navbutton. You could also use the SetAll method to set this property:IF TYPE ("cTableAlias") = 'C' This.SetAll("TableAlias", "cTableAlias")ENDIF However, this would cause an error if an object were ever added to the class that did not have a TableAlias property.

ENDDEFINE

End class definition.

Once you have defined the class, you can subclass it or add it to a form.

Creating a Subclass Based on the New Class

You can also create subclasses based on vcr that have additional buttons such as Search, Edit, Save, and Quit. For example, vcr2 includes a Quit button:

Definition of a Table Navigation Control Subclass

Code Comments

DEFINE CLASS vcr2 AS vcr

ADD OBJECT cmdQuit AS

COMMANDBUTTON WITH ;

Caption = "Quit",;

Height = 25, ;

Width = 50

Width = THIS.Width + THIS.cmdQuit.Width

cmdQuit.Left = THIS.Width - ;

THIS.cmdQuit.Width

Define a class based on vcr and add a command button to it.

PROCEDURE cmdQuit.CLICK

RELEASE THISFORM

ENDPROC

When the user clicks cmdQuit, this code releases the form.

ENDDEFINE

End class definition.

Vcr2 has everything that vcr does, plus the new command button, and you don't have to rewrite any of the existing code.

Changes to VCR Reflected in the Subclass

Because of inheritance, changes to the parent class are reflected in all subclasses based on the parent. For example, you could let the user know that the bottom of the table has been reached by changing the IF EOF( ) statement in navNext.Click to the following:

IF EOF( )
   GO BOTTOM
   SET MESSAGE TO "Bottom of the table"
ELSE
   SET MESSAGE TO
ENDIF

You could let the user know that the top of the table has been reached by changing the IF BOF( ) statement in navPrior.Click to the following:

IF BOF()
   GO TOP
   SET MESSAGE TO "Top of the table"
ELSE
   SET MESSAGE TO
ENDIF

If these changes are made to the navNext and navPrior classes, they will also apply automatically to the appropriate buttons in vcr and vcr2.

Adding VCR to a Form Class

Once vcr is defined as a control, the control can be added in the definition of a container. For example, the following code added to Navclass.prg defines a form with added navigation buttons:

DEFINE CLASS NavForm AS Form
   ADD OBJECT oVCR AS vcr
ENDDEFINE

Running the Form Containing VCR

Once the form subclass is defined, you can display it by loading the class definition, creating an object based on the subclass and calling the Show method for the form:

SET PROCEDURE TO navclass ADDITIVE
frmTest = CREATEOBJECT("navform")
frmTest.Show

If you don't call the SetTable method of oVCR (the VCR object in NavForm) when the user clicks the navigation buttons, the record pointer moves in the table in the currently selected work area. You can call the SetTable method to specify what table to move through.

frmTest.oVCR.SetTable("customer")

Note

When the user closes the form, frmTest is set to a null value (.NULL.). To release the object variable from memory, use the RELEASE command. Object variables created in program files are released from memory when the program is completed.

See Also

Reference

Caption Property (Visual FoxPro)
Height Property
SetAll Method

Concepts

Defining a Grid Control

Other Resources

Object-Oriented Programming